package com.jrew.gae.wcs.spring.services;

import java.util.Iterator;
import java.util.List;
import java.util.logging.Logger;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.FlushModeType;
import javax.persistence.Query;

import org.mortbay.log.Log;

import com.jrew.gae.wcs.entities.PlayerStats;
import com.jrew.gae.wcs.spring.services.StatsManagerService;
import com.jrew.util.EntityManagerFactoryStorage;

/**
 *
 */
public class StatsManagerServiceImpl implements StatsManagerService {

	/**
	 * 
	 */
	private static final Logger log = Logger.getLogger(StatsManagerServiceImpl.class.getName());
	
	public void updatePlayerStats(PlayerStats playerStats) {
		
		EntityManagerFactory emFactory = EntityManagerFactoryStorage.getInstance();
		EntityManager entityManager = emFactory.createEntityManager(); 
		try{
			List<PlayerStats> obsoletePlayerStats = entityManager.
				 		 createQuery( "SELECT p FROM PlayerStats p WHERE p.playerId = :playerId AND p.level = :level AND p.locale = :locale")
			        	.setParameter("playerId", playerStats.getPlayerId())
			        	.setParameter("level", playerStats.getLevel())
			        	.setParameter("locale", playerStats.getLocale())
			        	.getResultList();
			if(obsoletePlayerStats != null && !obsoletePlayerStats.isEmpty()){
				// Player passed this level before. So, we need to update scored if new value > old scores value
				PlayerStats oldPlayerStats = obsoletePlayerStats.get(0);
				int newScores = playerStats.getScores();
				int oldScores = oldPlayerStats.getScores();
				if(oldScores < newScores){
					// Update player scores with new value
					oldPlayerStats.setScores(newScores);
					entityManager.persist(oldPlayerStats);
					StringBuffer message = new StringBuffer();
					message.append("Update player stats. Name: ")
					   .append(playerStats.getPlayerName())
					   .append(" Level: ")
					   .append(playerStats.getLevel())
					   .append(" Locale: ")
					   .append(playerStats.getLocale())
					   .append(" Old scores: ")
					   .append(oldScores)
					   .append(" New scores: ")
					   .append(newScores);
					log.info(message.toString());
				}
			} else {
				// Player didn't pass this level before. Just save stats to database
				entityManager.persist(playerStats);
				StringBuffer message = new StringBuffer();
				message.append("Save new player stats. Name: ")
				   .append(playerStats.getPlayerName())
				   .append(" Level: ")
				   .append(playerStats.getLevel())
				   .append(" Locale: ")
				   .append(playerStats.getLocale())
				   .append(" Scores: ")
				   .append(playerStats.getScores());
			log.info(message.toString());
			}
		} catch (Exception exp) {
			exp.printStackTrace();
		} finally {
			entityManager.close();
		}
	}
	
	public List<PlayerStats> getStats(int level, String locale, int number) {
		List<PlayerStats> stats = null;
		EntityManagerFactory emFactory = EntityManagerFactoryStorage.getInstance();
		EntityManager entityManager = emFactory.createEntityManager();
		try {
			Query query = entityManager.createQuery( "SELECT p FROM PlayerStats p WHERE p.level = :level AND p.locale = :locale ORDER BY p.scores DESC")
		       	 					   .setParameter("level", level)
		       	 					   .setParameter("locale", locale); 
			query.setMaxResults(number);
			stats = query.getResultList();
			if(stats != null){
				Iterator iterator = stats.iterator();
				while(iterator.hasNext()) iterator.next();
			}
		} catch(Exception exp) {
			exp.printStackTrace();
		} finally {
			entityManager.close();
		}
		return stats;
	}
	
}
